﻿using Garnet.client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace GarnetClientSample
{
    public class GarnetDbManager
    {
        private GarnetClient _client;
        private string _host;
        private int _port;
        private int _currentDb = 0;

        public GarnetDbManager(string host = "localhost", int port = 6379)
        {
            _host = host;
            _port = port;
        }

        /// <summary>
        /// 连接到 Garnet 服务器
        /// </summary>
        public void Connect()
        {
            _client = new GarnetClient(new IPEndPoint(IPAddress.Parse(_host), _port));
            _client.Connect();
        }

        /// <summary>
        /// 写入字符串数据
        /// </summary>
        public async Task<bool> SetAsync(string key, string value)
        {
            try
            {
                var result = await _client.StringSetAsync(key, value);
                Console.WriteLine($"[DB{_currentDb}] SET {key} = {value} => {result}");
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"写入数据失败: {ex.Message}");
                return false;
            }
        }

        public async Task<bool> SetMultipleAsync(params (string key, string value)[] pairs)
        {
            try
            {
                foreach (var (key, value) in pairs)
                {
                    await _client.StringSetAsync(key, value);
                }
                Console.WriteLine($"批量写入 {pairs.Length} 个键值对");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量写入失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 批量读取字符串数据
        /// </summary>
        public async Task<string[]> GetMultipleAsync(params string[] keys)
        {
            try
            {
                var values = new string[keys.Length];
                for (int i = 0; i < keys.Length; i++)
                {
                    values[i] = await _client.StringGetAsync(keys[i]);
                }
                Console.WriteLine($"批量读取 {keys.Length} 个键");
                return values;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量读取失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取所有匹配模式的键（使用 KEYS 命令，生产环境慎用）
        /// </summary>
        public async Task<string[]> GetKeysAsync(string pattern = "*")
        {
            try
            {
                var result = await _client.ExecuteForStringArrayResultAsync($"KEYS", [pattern]);
                Console.WriteLine($"KEYS {pattern} => {result}");
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取键列表失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 批量删除键
        /// </summary>
        public async Task<int> DeleteMultipleAsync(params string[] keys)
        {
            try
            {
                var result = await _client.ExecuteForStringResultAsync($"DEL", keys);
                int count = int.Parse(result);
                Console.WriteLine($"批量删除 {count} 个键");
                return count;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量删除失败: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 读取字符串数据
        /// </summary>
        public async Task<string> GetAsync(string key)
        {
            try
            {
                var value = await _client.StringGetAsync(key);
                Console.WriteLine($"[DB{_currentDb}] GET {key} => {value}");
                return value;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取数据失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 带过期时间的写入（使用 SETEX 命令，单位：秒）
        /// </summary>
        public async Task<bool> SetWithExpiryAsync(string key, string value, int expireSeconds)
        {
            try
            {
                // 使用 SET 命令的 EX 选项：SET key value EX seconds
                var result = await _client.ExecuteForStringResultAsync("SET", [key, value, "EX", expireSeconds.ToString()]);
                Console.WriteLine($"SET {key} = {value} EX {expireSeconds}秒 => {result}");
                return result == "OK";
            }
            catch (Exception ex)
            {
                Console.WriteLine($"写入数据失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 带过期时间的写入（使用 TimeSpan）
        /// </summary>
        public async Task<bool> SetWithExpiryAsync(string key, string value, TimeSpan expiry)
        {
            return await SetWithExpiryAsync(key, value, (int)expiry.TotalSeconds);
        }

        /// <summary>
        /// 删除键
        /// </summary>
        public async Task<bool> DeleteAsync(string key)
        {
            try
            {
                var result = await _client.KeyDeleteAsync(key);
                Console.WriteLine($"[DB{_currentDb}] DEL {key} => {result}");
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"删除数据失败: {ex.Message}");
                return false;
            }
        }

        public async Task<bool> ExistsAsync(string key)
        {
            try
            {
                var result = await _client.ExecuteForStringResultAsync($"EXISTS", [key]);
                var exists = result == "1";
                Console.WriteLine($"EXISTS {key} => {exists}");
                return exists;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查键失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取当前数据库索引
        /// </summary>
        public int GetCurrentDb()
        {
            return _currentDb;
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            _client?.Dispose();
            Console.WriteLine("已断开连接");
        }
    }
}